package sf.dynamicsql;

import org.mybatis.dynamic.sql.delete.render.DeleteStatementProvider;
import org.mybatis.dynamic.sql.insert.render.BatchInsert;
import org.mybatis.dynamic.sql.insert.render.GeneralInsertStatementProvider;
import org.mybatis.dynamic.sql.insert.render.InsertSelectStatementProvider;
import org.mybatis.dynamic.sql.insert.render.InsertStatementProvider;
import org.mybatis.dynamic.sql.insert.render.MultiRowInsertStatementProvider;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import sf.common.wrapper.Page;

import java.sql.Connection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;

public interface DynmicSQLInf {
    /**
     * @param conn
     * @param provider
     * @param records
     * @param insertFast
     * @param batchSize
     * @param pkeys
     * @param keyValues
     * @param <T>
     * @return
     */
    <T> int[] insertBatch(Connection conn, BatchInsert<T> provider, List<T> records, boolean insertFast,
                          int batchSize, List<String> pkeys, List<Map<String, Object>> keyValues);

    /**
     * @param conn
     * @param insertFast
     * @param batchSize
     * @param pkeys
     * @param keyValues
     * @param provider
     * @param <T>
     * @return
     */
    <T> int[] insertBatch(Connection conn, boolean insertFast,
                          int batchSize, List<String> pkeys, List<Map<String, Object>> keyValues, MultiRowInsertStatementProvider<T> provider);

    /**
     * @param conn
     * @param pkeys
     * @param keyValues
     * @param provider
     * @param <T>
     * @return
     */
    <T> int insert(Connection conn, List<String> pkeys, Map<String, Object> keyValues, InsertStatementProvider<T> provider);

    /**
     * @param conn
     * @param pkeys
     * @param keyValues
     * @param provider
     * @return
     */
    int insert(Connection conn, List<String> pkeys, Map<String, Object> keyValues, GeneralInsertStatementProvider provider);

    /**
     * @param conn
     * @param pkeys
     * @param keyValues
     * @param provider
     * @return
     */
    int insertSelect(Connection conn, List<String> pkeys, Map<String, Object> keyValues, InsertSelectStatementProvider provider);

    /**
     * @param conn
     * @param provider
     * @return
     */
    int update(Connection conn, UpdateStatementProvider provider);

    /**
     * @param conn
     * @param provider
     * @return
     */
    int delete(Connection conn, DeleteStatementProvider provider);

    /**
     * @param conn
     * @param start
     * @param limit
     * @param beanClass
     * @param provider
     * @param <T>
     * @return
     */
    <T> Page<T> selectPage(Connection conn, long start, int limit, Class<T> beanClass, SelectStatementProvider provider);

    /**
     * @param conn
     * @param start
     * @param limit
     * @param beanClass
     * @param countProvider
     * @param listProvider  不能包含分页参数
     * @param <T>
     * @return
     */
    <T> Page<T> selectPageRaw(Connection conn, long start, int limit, Class<T> beanClass, SelectStatementProvider countProvider,
                              SelectStatementProvider listProvider);

    /**
     * @param conn
     * @param provider
     * @return
     */
    Object[] selectArray(Connection conn, SelectStatementProvider provider);

    /**
     * @param conn
     * @param beanClass
     * @param provider
     * @param <T>
     * @return
     */
    <T> List<T> selectList(Connection conn, Class<T> beanClass, SelectStatementProvider provider);

    /**
     * @param conn
     * @param beanClass
     * @param provider
     * @param start
     * @param limit
     * @param <T>
     * @return
     */
    <T> List<T> selectList(Connection conn, Class<T> beanClass, SelectStatementProvider provider, long start, int limit);

    /**
     * @param conn
     * @param beanClass
     * @param provider
     * @param <T>
     * @return
     */
    <T> T selectOne(Connection conn, Class<T> beanClass, SelectStatementProvider provider);

    /**
     * @param conn
     * @param provider
     * @return
     */
    List<Map<String, Object>> select(Connection conn, SelectStatementProvider provider);

    /**
     * @param conn
     * @param ormIt
     * @param returnClass
     * @param provider
     * @param <T>
     */
    <T> void selectIterator(Connection conn, Consumer<Iterable<T>> ormIt, Class<T> returnClass, SelectStatementProvider provider);

    /**
     * @param conn
     * @param ormStream
     * @param returnClass
     * @param provider
     * @param <T>
     */
    <T> void selectStream(Connection conn, Consumer<Stream<T>> ormStream, Class<T> returnClass, SelectStatementProvider provider);
}
